package auth

import (
	"context"
	"coze_for_sdk/config"
	"coze_for_sdk/logger"
	"fmt"
	"os"
	"strconv"
	"sync"
	"time"

	"github.com/coze-dev/coze-go"
)

var (
	cozeAccessToken string
	tokenMutex      sync.RWMutex
)

// GetCozeAccessToken 获取 token，如果过期会自动更新
func GetCozeAccessToken() string {
	tokenMutex.RLock()
	token := cozeAccessToken
	tokenMutex.RUnlock()

	// 如果 token 为空，获取新的
	if token == "" {
		return refreshAccessToken()
	}

	// 检查 token 是否过期
	accessTokenOutTime, err := os.ReadFile("coze_token/access_token_out_time.txt")
	if err != nil {
		return refreshAccessToken()
	}

	accessTokenOutTimeInt, err := strconv.Atoi(string(accessTokenOutTime))
	if err != nil {
		return refreshAccessToken()
	}

	// 如果 token 过期，刷新它
	if time.Now().Unix() >= int64(accessTokenOutTimeInt) {
		return refreshAccessToken()
	}

	return token
}

// refreshAccessToken 刷新 token
func refreshAccessToken() string {
	tokenMutex.Lock()
	defer tokenMutex.Unlock()

	// 再次检查，避免并发刷新
	if time.Now().Unix() < getTokenExpireTime() {
		return cozeAccessToken
	}

	newToken := getNewAccessToken()
	cozeAccessToken = newToken
	return newToken
}

// getTokenExpireTime 获取 token 过期时间
func getTokenExpireTime() int64 {
	accessTokenOutTime, err := os.ReadFile("coze_token/access_token_out_time.txt")
	if err != nil {
		return 0
	}
	accessTokenOutTimeInt, err := strconv.Atoi(string(accessTokenOutTime))
	if err != nil {
		return 0
	}
	return int64(accessTokenOutTimeInt)
}

// 获取新的access token
func getNewAccessToken() string {
	cfg := config.DefaultConfig

	// 读取私钥文件
	privateKeyBytes, err := os.ReadFile(cfg.Coze.JwtOauthPrivateKeyFilePath)
	if err != nil {
		logger.Error("Error reading private key file: %v\n", err)
		// 如果私钥文件读取失败，使用配置中的私钥
		privateKeyBytes = []byte(cfg.Coze.JwtOauthPrivateKey)
	}

	// 创建 JWT OAuth 客户端
	var ttl int = 24 * 60 * 60
	oauth, err := coze.NewJWTOAuthClient(coze.NewJWTOAuthClientParam{
		ClientID:      cfg.Coze.JwtOauthClientId,
		PublicKey:     cfg.Coze.JwtOauthPublicKeyId,
		PrivateKeyPEM: string(privateKeyBytes),
		TTL:           &ttl,
	}, coze.WithAuthBaseURL(cfg.Coze.ApiBase))
	if err != nil {
		logger.Error("Error creating JWT OAuth client: %v\n", err)
		return ""
	}

	// 获取新的 access token
	accessToken, err := oauth.GetAccessToken(context.Background(), nil)
	if err != nil {
		logger.Error("Error getting access token: %v\n", err)
		return ""
	}

	// 保存新的 token 和过期时间
	os.WriteFile("coze_token/access_token.txt", []byte(accessToken.AccessToken), 0644)
	os.WriteFile("coze_token/access_token_out_time.txt", []byte(fmt.Sprintf("%d", accessToken.ExpiresIn-100)), 0644)

	return accessToken.AccessToken
}
